package com.ls.utils.login;

import com.ls.entity.SysUser;
import com.ls.exception.CommonExceptionEnums;
import com.ls.exception.LoginOutOfDateException;
import com.ls.exception.MissTokenException;
import com.ls.utils.redis.RedisClient;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

/**
 * @Description 登录用户的参数解析器，将含有 @CurrentUser 注解的方法参数注入当前登录用户
 * @Author TangQuanBin
 * @Date 2019/9/14 17:21
 * @Version 1.0
 **/
public class MallUserArgumentResolver implements HandlerMethodArgumentResolver {

    private static final Logger LOGGER = LoggerFactory.getLogger(MallUserArgumentResolver.class);

    /**
     * redis 相关
     */
    @Autowired
    private RedisClient redisClient;

    /**
     * 返回true时才会执行下面的resolveArgument方法
     *
     * @param parameter
     * @return
     */
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.getParameterType().isAssignableFrom(SysUser.class)
                && parameter.hasParameterAnnotation(CurrentUser.class);
    }

    /**
     * 商城----获取用户信息并返回
     *
     * @param parameter
     * @param mavContainer
     * @param webRequest
     * @param binderFactory
     * @return 返回用户信息
     * @throws Exception
     */
    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        //从请求头中获取sessionId
        String sessionId = webRequest.getSessionId();
        if (StringUtils.isNotBlank(sessionId)) {
            //根据sessionId获取token
            String token = redisClient.getJsonString(sessionId);
            if (StringUtils.isBlank(token)) {
                //token丢失
                throw new MissTokenException(CommonExceptionEnums.MISS_TOKEN.getMessage());
            }
            //根据token从Redis中获取用户信息
            SysUser user = redisClient.getValue(token, SysUser.class);
            if (user != null) {
                return user;
            } else {
                //登录信息失效，需重新登录
                throw new LoginOutOfDateException(CommonExceptionEnums.LOGIN_OUT_OF_DATE.getMessage());
            }

        } else {
            //token丢失
            throw new MissTokenException("会话过期，请重新登录！");
        }
    }
}